package cate.game.role.bag.equip;

import cate.common.table.d.GDObj;
import cate.common.table.item.IBagItemTpl;
import cate.common.table.item.equip.row.EquipBaseRow;
import cate.common.util.GameResult;
import cate.game.attr.EquipsPowerAttrPart;
import cate.game.attr.PowerAttrPart;
import cate.game.event.hero.HeroPowerChangeEvent;
import cate.game.play.support.PlayBuildContext;
import cate.game.role.Role;
import cate.game.role.RoleDependent;
import cate.game.role.bag.IBagContainer;
import cate.game.role.bag.gem.Gem;
import cate.game.role.bag.hero.Hero;
import cate.game.role.bag.hero.OnHeroItem;
import cate.game.util.GameKit;
import com.fasterxml.jackson.annotation.JsonIgnore;
import cp.solution.util.collection.MapKit;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;
import org.springframework.data.annotation.Transient;

import java.util.*;

@SuppressWarnings("unchecked")
public class EquipsOn extends RoleDependent implements OnHeroItem<Equip> {
    @JsonIgnore
    @Transient
    public transient Hero owner;

    @NoteField(value = "英雄身上的装备们", detail = "Map<部位:Byte, 装备信息>")
    public Map<Byte, Equip> equipMap;

    public void initialize(Hero owner,Role role){
        super.initialize(role);
        this.owner = owner;
        if(equipMap == null){
            equipMap = new HashMap<>();
        }
        equipMap.values().forEach(a -> a.initialize(role));
    }

    @Override
    @JsonIgnore
    public IBagContainer<Equip> getItemBag() {
        return role.getBag().getBag(GDObj.Type.EQUIP);
    }

    @Override
    public Map<Byte, Equip> getPosItems() {
        return equipMap;
    }

    @Override
    public void doRealOn(byte pos, Equip equip) {
        // 穿上装备就还uid
        EquipBaseRow equipBaseRow = equip.getTpl(role.getGame().fight.getPlayBuildContext());
        if (equipBaseRow == null || equipBaseRow.unique() || equip.unique()) {
            equipMap.put(pos, equip);
        } else {
            Equip templeEquip = equip.copy();
            templeEquip.uid = GameKit.uid();
            templeEquip.num = 1;
            templeEquip.initialize(role);
            equipMap.put(pos, templeEquip);
        }
    }

    @Override
    public void doRealOff(byte pos, Equip equip) {
        this.equipMap.remove(pos);
    }

    @Override
    @JsonIgnore
    public PowerAttrPart getPowerAttrPart(PlayBuildContext ctx) {
        return new EquipsPowerAttrPart(ctx,this);
    }

    @JsonIgnore
    public List<Integer> getSkills() {
        return new ArrayList<>();
    }

    @Override
    public EquipsOn copy() {
        EquipsOn cp = new EquipsOn();
        cp.equipMap = MapKit.cloneDeep(this.equipMap);
        cp.initialize(this.owner, this.role);
        return cp;
    }

    @Override
    public GameResult<Byte> on(PlayBuildContext ctx, Hero hero, byte pos, Equip e){
        GameResult<Byte> r = new GameResult<>();
        if (e == null || e.num <= 0) {
            return r.fail("物品不存在");
        }
        Map<Byte, Gem> gemMap = new HashMap<>();
        //要再判断一次这个位置是否存在装备，不能直接走off
        if (getPosItem(pos) != null) {
            //脱下之前的
            GameResult<Map<Byte, Gem>> offRes = off(ctx, pos, e);
            if (!offRes.ok()) {
                return r.fail(offRes);
            }
            gemMap.putAll(offRes.data);
        }
        //替换宝石
        if (!gemMap.isEmpty()) {
            for (Map.Entry<Byte, Gem> gemEntry : gemMap.entrySet()) {
                owner.getRole().getGame().train.gem.onGemRes(owner.getRole(), e, owner, gemEntry.getValue());
            }
        }
        doRealOn(pos,e);
        r.data = pos;
        getItemBag().notReallyRemoveItemByUid(e.uid,1,null);

        //英雄战力变更
        if (hero != null) {
            publishEvent(ctx, new HeroPowerChangeEvent(hero.getRole(), hero));
        }
        return r;
    }

    public GameResult<Map<Byte, Gem>> off(PlayBuildContext ctx, byte pos, Equip toOn){
        GameResult<Map<Byte, Gem>> r = new GameResult<>();
        Equip e = getPosItem(pos);
        if(e == null){
            return r.fail("物品不存在");
        }
        //卸下宝石
        Map<Byte, Gem> posGems = new HashMap<>();
        if (e.hasGem() && toOn.getTpl(ctx).canGem) {
            for (Map.Entry<Byte, Gem> gemEntry : e.gemsOn.getPosItems().entrySet()) {
                posGems.put(gemEntry.getKey(), gemEntry.getValue());
                e.gemsOn.doRealOff(gemEntry.getKey(), gemEntry.getValue());
            }
        }
        //获得之前身上的
        EcResult<Void> addRes;
        IBagItemTpl row = e.getTpl(ctx);
        if(row == null || row.unique() || e.unique()){
            addRes = getItemBag().addItem(e,null);
        }else{
            addRes = getItemBag().addItem(e.tid,1,null);
        }
        if(!addRes.ok()){
            return r.fail(addRes.message);
        }
        doRealOff(pos,e);
        r.data = posGems;
        return r;
    }
}
